#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include "prime.h"
#include <vector>
#include <iostream>
using namespace std;

pthread_mutex_t         mutex = PTHREAD_MUTEX_INITIALIZER;

typedef struct prime_opt
{
    int start;
    int step;

} prime_opt;

void display_usage()
{
    printf("Please use -n option to specify thread count, like -n 2...\n");

}

vector<int>* result = new vector<int>;

bool contains_circular(vector<int> v, int n){
            
    pthread_mutex_lock(&mutex);
    int s = v.size();
    for (int i=0; i<s; i++){
        if (is_circular(n,v[i])){
            pthread_mutex_unlock(&mutex);
            return true;
        }
            
    }
     pthread_mutex_unlock(&mutex);
    return false;
 
}

void *get_primes(void *opt)
{
    struct prime_opt *options = (prime_opt *)opt;
    int start = options->start;
    int step = options->step;
    
    for(int i=start; i<1000000; i+=step) {
        if(rounder(i)&&!contains_circular(*result,i)) {
            pthread_mutex_lock(&mutex);
            result->insert(result->end(),i);
            pthread_mutex_unlock(&mutex);
            
        }
    }
    void *res = NULL;
    res = result;
    pthread_exit( (void *)res);
}

int main(int argc, char *argv[])
{
    if (argc !=3) {
        display_usage();
        return 0;
    }
    int opt = 0;
    int thread_count = 1;
    while ( opt != -1 )
    {
        switch ( opt )
        {
        case 'n':
            thread_count = atoi(optarg);
            break;


        case 'h':   /* намеренный проход в следующий case-блок */
        case '?':
            display_usage();
            break;

        default:
            /* сюда на самом деле попасть невозможно. */
            break;
        }

        opt = getopt( argc, argv, "n:" );
    }
    printf("thread count is : %d \n", thread_count);

    pthread_t threads[thread_count];
    vector<int> res;
    int rc;
    long t;
    for (t = 0; t < thread_count; t++)
    {
        printf("In main: creating thread %ld\n", t);
        struct prime_opt *opt = (prime_opt *)malloc(sizeof(int) * 2);
        opt->start = 1+(t+1)*2;
        opt->step = thread_count*2;
        rc = pthread_create(&threads[t], NULL, get_primes, (void *)opt);
    }

    for (t = 0; t < thread_count; t++)
    {
        vector<int>* current;
        pthread_join(threads[t], (void **)&current);
        //res.insert( res.end(), current->begin(), current->end() );
    }

    for( std::vector<int>::const_iterator i = result->begin(); i != result->end(); ++i)
        std::cout << *i << ' ';
    cout << endl;
    pthread_exit(NULL);

    return 0;

}
